package com.elitesland.security.config;

import com.elitesland.core.base.ApiCode;
import com.elitesland.core.base.ApiResult;
import com.elitesland.core.util.HttpServletResponseUtil;
import com.elitesland.security.TokenProvider;
import com.elitesland.security.config.bean.JwtProperties;
import com.elitesland.security.config.bean.LoginProperties;
import com.elitesland.security.service.OnlineUserService;
import com.elitesland.security.service.entity.JwtUserDto;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;

import java.util.HashMap;
import java.util.Map;

/**
 * <p>
 * 功能说明
 * </p>
 *
 * @author Mir
 * @date 2020/7/4
 */
@Slf4j
@Configuration
@RequiredArgsConstructor
public class JwtConfig {

    private final OnlineUserService onlineUserService;

    private final TokenProvider tokenProvider;

    private final JwtProperties properties;

    private final LoginProperties loginProperties;

    @Bean
    public AuthenticationSuccessHandler authenticationSuccessHandler() {
        return (request, response, authentication) -> {
            if (response.isCommitted()) {
                log.debug("Response has already been committed!!!");
                return;
            }
            val token = tokenProvider.createToken(authentication);
            val jwtUserDto = (JwtUserDto) authentication.getPrincipal();
            onlineUserService.save(jwtUserDto, token, request);
            Map<String, Object> authInfo = new HashMap<>(2) {
                private static final long serialVersionUID = -7157230580904317221L;

                {
                    put("token", properties.getTokenStartWith() + token);
                    put("user", jwtUserDto);
                }
            };

            if (loginProperties.isSingleLogin()) {
                onlineUserService.checkLoginOnUser(jwtUserDto.getUsername(), token);
            }

            try {
                HttpServletResponseUtil.printJSON(response, ApiResult.ok(authInfo));
            } catch (Exception e) {
                e.printStackTrace();
            }
        };
    }

    @Bean
    public AuthenticationFailureHandler authenticationFailureHandler() {
        return (request, response, exception) -> {
            try {
                if (exception instanceof BadCredentialsException) {
                    HttpServletResponseUtil.printJSON(response, ApiResult.fail(ApiCode.AUTHENTICATION_EXCEPTION, "账号密码不正确"));
                } else {
                    HttpServletResponseUtil.printJSON(response, ApiResult.fail(exception.getMessage()));
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        };
    }
}
